package com.zp.base.admin.controller;

import com.zp.base.admin.common.aspect.AddOperatorLog;
import com.zp.base.admin.common.constant.BizCodeEnum;
import com.zp.base.admin.common.utils.PageUtils;
import com.zp.base.admin.common.utils.R;
import com.zp.base.admin.config.SiteConfig;
import com.zp.base.admin.entity.OperatorLogEntity;
import com.zp.base.admin.entity.UserEntity;
import com.zp.base.admin.listener.SessionListener;
import com.zp.base.admin.service.DatabaseBakService;
import com.zp.base.admin.service.OperatorLogService;
import com.zp.base.admin.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ZhangPeng
 * @email zhangpeng98@aliyun.com
 * @create 2021-02-27 16:16
 */
@RequestMapping("/system")
@Controller
@Slf4j
public class SystemController {

    @Autowired
    private SiteConfig siteConfig;
    @Autowired
    UserService userService;
    @Autowired
    OperatorLogService operatorLogService;
    @Autowired
    BCryptPasswordEncoder passwordEncoder;
    @Autowired
    DatabaseBakService databaseBakService;

    @GetMapping("/login")
    public String tpLogin(Model model) {
        model.addAttribute("siteName", siteConfig.getSiteName());
        model.addAttribute("siteUrl", siteConfig.getSiteUrl());
        return "admin/system/login";
    }


    @AddOperatorLog(content = "退出后台系统")
    @GetMapping("/logout")
    public String logout(HttpServletRequest request) {
        return "redirect:/logout";
    }

    /*@PostMapping("/login")
    @AddOperatorLog(content = "登录后台系统")
    @ResponseBody
    public R login(@Valid UserEntity userEntity, BindingResult bindingResult, String captcha, HttpServletRequest request) {
        //检查用户信息  使用JSR303校验
        if (bindingResult.hasErrors()) {
            if (bindingResult.hasErrors()) {
                return ValidUtil.getErrorInfo(bindingResult);
            }
        }
        *//*if (userEntity == null) {
            return R.error(BizCodeEnum.VALID_EXCEPTION.getCode(), BizCodeEnum.VALID_EXCEPTION.getMsg());
        }
        if (StringUtils.isEmpty(userEntity.getUsername())) {
            return R.error(BizCodeEnum.USERNAME_NOT_NULL.getCode(), BizCodeEnum.USERNAME_NOT_NULL.getMsg());
        }
        if (StringUtils.isEmpty(userEntity.getPassword())) {
            return R.error(BizCodeEnum.PASSWORD_NOT_NULL.getCode(), BizCodeEnum.PASSWORD_NOT_NULL.getMsg());
        }*//*
        //检查验证码
        if (StringUtils.isEmpty(captcha.trim())) {
            return R.error(BizCodeEnum.CAPTCHA_NOT_NULL.getCode(), BizCodeEnum.CAPTCHA_NOT_NULL.getMsg());
        }
        //校验验证码是否正确
        Object adminLogin = request.getSession().getAttribute("adminLogin");
        if (adminLogin == null) {
            return R.error(BizCodeEnum.SESSION_IS_INVALID.getCode(), BizCodeEnum.SESSION_IS_INVALID.getMsg());
        }
        if (!adminLogin.toString().equalsIgnoreCase(captcha)) {
            return R.error(BizCodeEnum.CAPTCHA_IS_ERROR.getCode(), BizCodeEnum.CAPTCHA_IS_ERROR.getMsg());
        }
        //查询数据库 判断用户
        UserEntity user = userService.findByUsername(userEntity.getUsername());
        if (user == null) {
            return R.error(BizCodeEnum.USER_NOT_EXIST.getCode(), BizCodeEnum.USER_NOT_EXIST.getMsg());
        }
        if (!userEntity.getPassword().equals(user.getPassword())) {
            return R.error(BizCodeEnum.PASSWORD_IS_ERROR.getCode(), BizCodeEnum.PASSWORD_IS_ERROR.getMsg());
        }
        //登录成功 把用户保存到session 清空session中的验证码
        request.getSession().setAttribute("user", user);
        request.getSession().removeAttribute("adminLogin");
        return R.ok();
    }
*/
    @GetMapping("/index")
    public String index(Model model) {
        model.addAttribute("siteName", siteConfig.getSiteName());

        //获取最新的10条操作日志
        List<OperatorLogEntity> operatorLogs = operatorLogService.getNewestOperatorLog(10);
        model.addAttribute("operatorLogs", operatorLogs);
        model.addAttribute("databaseBackupTotal", databaseBakService.count());
        model.addAttribute("userTotal", userService.count());
        model.addAttribute("onlineUserTotal", SessionListener.onlineUserTotal);
        model.addAttribute("operatorLogTotal", operatorLogService.count());

        return "admin/system/index";
    }

    /**
     * 去修改个人信息页面
     *
     * @return
     */
    @GetMapping("/update_userinfo")
    @AddOperatorLog(content = "查看了个人信息")
    public String toUpdateUserInfo() {
        return "admin/system/update_userinfo";
    }

    /**
     * 修改个人信息
     *
     * @param userEntity
     * @return
     */
    @PostMapping("/update_userinfo")
    @AddOperatorLog(content = "修改了个人信息")
    public String updateUserInfo(UserEntity userEntity) {
        //获取登录用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserEntity principal = (UserEntity) authentication.getPrincipal();
        //更新SpringSecurity保存的登录用户信息
        principal.setUpdateTime(new Date());
        principal.setHeadPic(userEntity.getHeadPic());
        principal.setEmail(userEntity.getEmail());
        principal.setMobile(userEntity.getMobile());
        //先修改数据库 再修改SpringSecurity保存的登录用户信息
        userService.updateById(principal);
        SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities()));
        return "redirect:update_userinfo";
    }

    /**
     * 去修改密码页面
     *
     * @return
     */
    @GetMapping("/update_pwd")
    public String toUpdatePwd() {
        return "admin/system/update_pwd";
    }

    /**
     * 修改密码
     *
     * @param oldpwd
     * @param newpwd
     * @return
     */
    @PostMapping("/update_pwd")
    @ResponseBody
    @AddOperatorLog(content = "修改密码")
    public R updatePwd(@RequestParam("oldPwd") String oldpwd, @RequestParam("newPwd") String newpwd) {
        //获取登录用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserEntity principal = (UserEntity) authentication.getPrincipal();
        if (!passwordEncoder.matches(oldpwd, principal.getPassword())) {
            return R.error(BizCodeEnum.ADMIN_USER_UPDATE_PWD_ERROR.getCode(), BizCodeEnum.ADMIN_USER_UPDATE_PWD_ERROR.getMsg());
        }
        if (StringUtils.isEmpty(newpwd)) {
            return R.error(BizCodeEnum.ADMIN_USER_UPDATE_PWD_EMPTY.getCode(), BizCodeEnum.ADMIN_USER_UPDATE_PWD_EMPTY.getMsg());
        }
        //更新SpringSecurity保存的登录用户信息
        principal.setUpdateTime(new Date());
        principal.setPassword(passwordEncoder.encode(newpwd));
        //先修改数据库 再修改SpringSecurity保存的登录用户信息
        userService.updateById(principal);
        SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities()));
        return R.ok();
    }

    /**
     * 查看日志
     *
     * @param operator
     * @param page
     * @param model
     * @return
     */
    @RequestMapping("/operator_log_list")
//    @AddOperatorLog(content = "查看了日志列表")
    @PreAuthorize("hasAuthority('system:operator_log_list')")
    public String operatorLogList(@RequestParam(name = "operator", defaultValue = "") String operator,
                                  @RequestParam(name = "currentPage", defaultValue = "1") String page, Model model) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("operator", operator);
        map.put("page", page);
        PageUtils pageUtils = operatorLogService.queryPage(map);

        model.addAttribute("pageBean", pageUtils);
        model.addAttribute("title", "日志列表");
        model.addAttribute("operator", operator);
        model.addAttribute("siteName", siteConfig.getSiteName());
        return "admin/system/operator_log_list";
    }

    /**
     * 删除日志
     */
    @PostMapping("/delete_operator_log")
    @ResponseBody
//    @AddOperatorLog(content = "删除日志")
    @PreAuthorize("hasAuthority('system:delete_operator_log')")
    public R delete(@RequestParam(name = "ids") String ids) {
        if (ids == null || ids.length() <= 0) {
            return R.error(BizCodeEnum.DELETE_LOG_NO_IDS.getCode(), BizCodeEnum.DELETE_LOG_NO_IDS.getMsg());
        }
        String[] split = ids.split(",");
        List<Long> collect = Arrays.stream(split).map(s -> Long.valueOf(s)).collect(Collectors.toList());
        boolean b = operatorLogService.removeByIds(collect);
        if (!b) {
            return R.error(BizCodeEnum.DELETE_LOG_ERROR.getCode(), BizCodeEnum.DELETE_LOG_ERROR.getMsg());
        }
        return R.ok();
    }


    /**
     * 删除日志
     */
    @PostMapping("/delete_all_operator_log")
    @ResponseBody
//    @AddOperatorLog(content = "清空了日志")
    @PreAuthorize("hasAuthority('system:delete_all_operator_log')")
    public R deleteAll() {
        boolean b = operatorLogService.deleteAll();
        if (!b) {
            return R.error(BizCodeEnum.DELETE_LOG_ERROR.getCode(), BizCodeEnum.DELETE_LOG_ERROR.getMsg());
        }
        return R.ok();
    }

}
